{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Flax basics\n",
    "\n",
    "Flax NNX is a new simplified API that is designed to make it easier to create, inspect, debug, and analyze neural networks in [JAX](https://jax.readthedocs.io/). It achieves this by adding first class support for Python reference semantics. This allows users to express their models using regular Python objects, which are modeled as PyGraphs (instead of pytrees), enabling reference sharing and mutability. Such API design should make PyTorch or Keras users feel at home.\n",
    "\n",
    "To begin, install Flax with `pip` and import necessary dependencies:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {
    "tags": [
     "skip-execution"
    ]
   },
   "outputs": [],
   "source": [
    "# ! pip install -U flax"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {},
   "outputs": [],
   "source": [
    "from flax import nnx\n",
    "import jax\n",
    "import jax.numpy as jnp"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## The Flax NNX Module system\n",
    "\n",
    "The main difference between the Flax `Module` and other Module systems in [Flax Linen](https://flax-linen.readthedocs.io/en/latest/api_reference/flax.linen/module.html) or [Haiku](https://dm-haiku.readthedocs.io/en/latest/notebooks/basics.html#Built-in-Haiku-nets-and-nested-modules) is that in NNX everything is **explicit**. This  means, among other things, that the NNX Module itself holds the state (such as parameters) directly, the [PRNG](https://jax.readthedocs.io/en/latest/random-numbers.html) state is threaded by the user, and all shape information must be provided on initialization (no shape inference).\n",
    "\n",
    "Let's begin by creating a Linear `Module`. As shown next, dynamic state is usually stored in `Param`s, and static state (all types not handled by NNX) such as integers or strings are stored directly. Attributes of type `jax.Array` and `numpy.ndarray` are also treated as dynamic states, although storing them inside Variables, such as Param, is preferred. Also the `Rngs` object can be used to get new unique keys based on a root PRNG key passed to the constructor."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {},
   "outputs": [],
   "source": [
    "class Linear(nnx.Module):\n",
    "  def __init__(self, din: int, dout: int, *, rngs: nnx.Rngs):\n",
    "    self.w = nnx.Param(rngs.params.uniform((din, dout)))\n",
    "    self.b = nnx.Param(jnp.zeros((dout,)))\n",
    "    self.din, self.dout = din, dout\n",
    "\n",
    "  def __call__(self, x: jax.Array):\n",
    "    return x @ self.w + self.b[None]"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Also note that the inner values of `Variable`s can be accessed using the `value` property, but for convenience they implement all numeric operators and can be used directly in arithmetic expressions (as shown in the code above).\n",
    "\n",
    "To initialize a Flax `Module`, you just call the constructor, and all the parameters of a Module are usually created eagerly. Since Modules hold their own state methods, you can call them directly without the need for a separate apply method.\n",
    "This can be very convenient for debugging, allowing you to directly inspect the entire structure of the model."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[[1.5643291  0.94782424 0.37971854 1.0724319  0.22112393]]\n"
     ]
    },
    {
     "data": {
      "text/html": [
       "<script> (()=>{ if (customElements.get('treescope-container') === undefined) { class TreescopeContainer extends HTMLElement { constructor() { super(); this.attachShadow({mode: \"open\"}); this.defns = {}; this.state = {}; } } customElements.define(\"treescope-container\", TreescopeContainer); } if (customElements.get('treescope-run-here') === undefined) { class RunHere extends HTMLElement { constructor() { super() } connectedCallback() { const run = child => { const fn = new Function(child.textContent); child.textContent = \"\"; fn.call(this); this.remove(); }; const child = this.querySelector(\"script\"); if (child) { run(child); } else { new MutationObserver(()=>{ run(this.querySelector(\"script\")); }).observe(this, {childList: true}); } } } customElements.define(\"treescope-run-here\", RunHere); } })(); </script> <treescope-container class=\"treescope_out_d5660a98b46e49b8a1073c1b8504eadb\" style=\"display:block\"></treescope-container> <treescope-run-here><script type=\"application/octet-stream\"> const root = ( Array.from(document.getElementsByClassName( \"treescope_out_d5660a98b46e49b8a1073c1b8504eadb\")) .filter((elt) => !elt.dataset.setup) )[0]; root.dataset.setup = 1; const msg = document.createElement(\"span\"); msg.style = \"color: #cccccc; font-family: monospace;\"; msg.textContent = \"(Loading...)\"; root.state.loadingMsg = msg; root.shadowRoot.appendChild(msg); root.state.chain = new Promise((resolve, reject) => { const observer = new IntersectionObserver((entries) => { for (const entry of entries) { if (entry.isIntersecting) { resolve(); observer.disconnect(); return; } } }, {rootMargin: \"1000px\"}); window.setTimeout(() => { observer.observe(root); }, 0); }); root.state.deferring = false; const _insertNode = (node) => { for (let oldScript of node.querySelectorAll(\"script\")) { let newScript = document.createElement(\"script\"); newScript.type = oldScript.type; newScript.textContent = oldScript.textContent; oldScript.parentNode.replaceChild(newScript, oldScript); } if (root.state.loadingMsg) { root.state.loadingMsg.remove(); root.state.loadingMsg = null; } root.shadowRoot.appendChild(node); }; root.defns.insertContent = ((contentNode, compressed) => { if (compressed) { root.state.deferring = true; } if (root.state.deferring) { root.state.chain = (async () => { await root.state.chain; if (compressed) { const encoded = contentNode.textContent; const blob = new Blob([ Uint8Array.from(atob(encoded), (m) => m.codePointAt(0)) ]); const reader = blob.stream().pipeThrough( new DecompressionStream(\"deflate\") ).pipeThrough( new TextDecoderStream(\"utf-8\") ).getReader(); const parts = []; while (true) { const step = await reader.read(); if (step.done) { break; } parts.push(step.value); } const tpl = document.createElement('template'); tpl.innerHTML = parts.join(\"\"); _insertNode(tpl.content); } else { _insertNode(contentNode.content); } })(); } else { _insertNode(contentNode.content); } }); </script></treescope-run-here><div style=\"display:none\"> <script type=\"application/octet-stream\" >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</script> <treescope-run-here><script type=\"application/octet-stream\"> const root = ( Array.from(document.getElementsByClassName( \"treescope_out_d5660a98b46e49b8a1073c1b8504eadb\")) .filter((elt) => !elt.dataset['step0']) )[0]; root.dataset['step0'] = 1; root.defns.insertContent( this.parentNode.querySelector('script[type=\"application/octet-stream\"]'), true ); this.parentNode.remove(); </script></treescope-run-here> </div>"
      ],
      "text/plain": [
       "<IPython.core.display.HTML object>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "text/html": [
       "<div style=\"display:none\"> <script type=\"application/octet-stream\" >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</script> <treescope-run-here><script type=\"application/octet-stream\"> const root = ( Array.from(document.getElementsByClassName( \"treescope_out_d5660a98b46e49b8a1073c1b8504eadb\")) .filter((elt) => !elt.dataset['step1']) )[0]; root.dataset['step1'] = 1; root.defns.insertContent( this.parentNode.querySelector('script[type=\"application/octet-stream\"]'), true ); this.parentNode.remove(); </script></treescope-run-here> </div>"
      ],
      "text/plain": [
       "<IPython.core.display.HTML object>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "model = Linear(2, 5, rngs=nnx.Rngs(params=0))\n",
    "y = model(x=jnp.ones((1, 2)))\n",
    "\n",
    "print(y)\n",
    "nnx.display(model)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "The above visualization by `nnx.display` is generated using the awesome\n",
    "[Treescope](https://treescope.readthedocs.io/en/stable/index.html#) library."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Stateful computation\n",
    "\n",
    "Implementing layers, such as `BatchNorm`, requires performing state updates during a forward pass. In Flax NNX, you just need to create a `Variable` and update its `.value` during the forward pass."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "counter.count[...] = Array(0, dtype=int32, weak_type=True)\n",
      "counter.count[...] = Array(1, dtype=int32, weak_type=True)\n"
     ]
    }
   ],
   "source": [
    "class Count(nnx.Variable): pass\n",
    "\n",
    "class Counter(nnx.Module):\n",
    "  def __init__(self):\n",
    "    self.count = Count(jnp.array(0))\n",
    "\n",
    "  def __call__(self):\n",
    "    self.count[...] += 1\n",
    "\n",
    "counter = Counter()\n",
    "print(f'{counter.count[...] = }')\n",
    "counter()\n",
    "print(f'{counter.count[...] = }')"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Mutable references are usually avoided in JAX. But Flax NNX provides sound mechanisms\n",
    "to handle them, as demonstrated in later sections of this guide."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Nested Modules\n",
    "\n",
    "Flax `Module`s can be used to compose other Modules in a nested structure. These can be assigned directly as attributes, or inside an attribute of any (nested) pytree type, such as a `list`, `dict`, `tuple`, and so on.\n",
    "\n",
    "The example below shows how to define a simple `MLP` by subclassing `Module`. The model consists of two `Linear` layers, a `Dropout` layer, and a `BatchNorm` layer. Note that we need to pass the `__call__` method the RNG state that we want the `Dropout` layer to use."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<script> (()=>{ if (customElements.get('treescope-container') === undefined) { class TreescopeContainer extends HTMLElement { constructor() { super(); this.attachShadow({mode: \"open\"}); this.defns = {}; this.state = {}; } } customElements.define(\"treescope-container\", TreescopeContainer); } if (customElements.get('treescope-run-here') === undefined) { class RunHere extends HTMLElement { constructor() { super() } connectedCallback() { const run = child => { const fn = new Function(child.textContent); child.textContent = \"\"; fn.call(this); this.remove(); }; const child = this.querySelector(\"script\"); if (child) { run(child); } else { new MutationObserver(()=>{ run(this.querySelector(\"script\")); }).observe(this, {childList: true}); } } } customElements.define(\"treescope-run-here\", RunHere); } })(); </script> <treescope-container class=\"treescope_out_5111ac75504b44448a5dd31dbaea5a09\" style=\"display:block\"></treescope-container> <treescope-run-here><script type=\"application/octet-stream\"> const root = ( Array.from(document.getElementsByClassName( \"treescope_out_5111ac75504b44448a5dd31dbaea5a09\")) .filter((elt) => !elt.dataset.setup) )[0]; root.dataset.setup = 1; const msg = document.createElement(\"span\"); msg.style = \"color: #cccccc; font-family: monospace;\"; msg.textContent = \"(Loading...)\"; root.state.loadingMsg = msg; root.shadowRoot.appendChild(msg); root.state.chain = new Promise((resolve, reject) => { const observer = new IntersectionObserver((entries) => { for (const entry of entries) { if (entry.isIntersecting) { resolve(); observer.disconnect(); return; } } }, {rootMargin: \"1000px\"}); window.setTimeout(() => { observer.observe(root); }, 0); }); root.state.deferring = false; const _insertNode = (node) => { for (let oldScript of node.querySelectorAll(\"script\")) { let newScript = document.createElement(\"script\"); newScript.type = oldScript.type; newScript.textContent = oldScript.textContent; oldScript.parentNode.replaceChild(newScript, oldScript); } if (root.state.loadingMsg) { root.state.loadingMsg.remove(); root.state.loadingMsg = null; } root.shadowRoot.appendChild(node); }; root.defns.insertContent = ((contentNode, compressed) => { if (compressed) { root.state.deferring = true; } if (root.state.deferring) { root.state.chain = (async () => { await root.state.chain; if (compressed) { const encoded = contentNode.textContent; const blob = new Blob([ Uint8Array.from(atob(encoded), (m) => m.codePointAt(0)) ]); const reader = blob.stream().pipeThrough( new DecompressionStream(\"deflate\") ).pipeThrough( new TextDecoderStream(\"utf-8\") ).getReader(); const parts = []; while (true) { const step = await reader.read(); if (step.done) { break; } parts.push(step.value); } const tpl = document.createElement('template'); tpl.innerHTML = parts.join(\"\"); _insertNode(tpl.content); } else { _insertNode(contentNode.content); } })(); } else { _insertNode(contentNode.content); } }); </script></treescope-run-here><div style=\"display:none\"> <script type=\"application/octet-stream\" >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</script> <treescope-run-here><script type=\"application/octet-stream\"> const root = ( Array.from(document.getElementsByClassName( \"treescope_out_5111ac75504b44448a5dd31dbaea5a09\")) .filter((elt) => !elt.dataset['step0']) )[0]; root.dataset['step0'] = 1; root.defns.insertContent( this.parentNode.querySelector('script[type=\"application/octet-stream\"]'), true ); this.parentNode.remove(); </script></treescope-run-here> </div>"
      ],
      "text/plain": [
       "<IPython.core.display.HTML object>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "text/html": [
       "<div style=\"display:none\"> <script type=\"application/octet-stream\" >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</script> <treescope-run-here><script type=\"application/octet-stream\"> const root = ( Array.from(document.getElementsByClassName( \"treescope_out_5111ac75504b44448a5dd31dbaea5a09\")) .filter((elt) => !elt.dataset['step1']) )[0]; root.dataset['step1'] = 1; root.defns.insertContent( this.parentNode.querySelector('script[type=\"application/octet-stream\"]'), true ); this.parentNode.remove(); </script></treescope-run-here> </div>"
      ],
      "text/plain": [
       "<IPython.core.display.HTML object>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "class MLP(nnx.Module):\n",
    "  def __init__(self, din: int, dmid: int, dout: int, *, rngs: nnx.Rngs):\n",
    "    self.linear1 = Linear(din, dmid, rngs=rngs)\n",
    "    self.dropout = nnx.Dropout(rate=0.1)\n",
    "    self.bn = nnx.BatchNorm(dmid, rngs=rngs)\n",
    "    self.linear2 = Linear(dmid, dout, rngs=rngs)\n",
    "\n",
    "  def __call__(self, x: jax.Array, rngs: nnx.Rngs):\n",
    "    x = nnx.gelu(self.dropout(self.bn(self.linear1(x)), rngs=rngs))\n",
    "    return self.linear2(x)\n",
    "\n",
    "model = MLP(2, 16, 5, rngs=nnx.Rngs(0))\n",
    "\n",
    "y = model(x=jnp.ones((3, 2)), rngs=nnx.Rngs(1))\n",
    "\n",
    "nnx.display(model)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Model surgery\n",
    "\n",
    "Flax `Module`s are mutable by default. This means that their structure can be changed at any time, which makes [model surgery](https://flax.readthedocs.io/en/latest/guides/surgery.html) quite easy, as any sub-Module attribute can be replaced with anything else, such as new Modules, existing shared Modules, Modules of different types, and so on. Moreover, `Variable`s can also be modified or replaced/shared.\n",
    "\n",
    "The following example shows how to replace the `Linear` layers in the `MLP` model from the previous example with `LoraLinear` layers:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<script> (()=>{ if (customElements.get('treescope-container') === undefined) { class TreescopeContainer extends HTMLElement { constructor() { super(); this.attachShadow({mode: \"open\"}); this.defns = {}; this.state = {}; } } customElements.define(\"treescope-container\", TreescopeContainer); } if (customElements.get('treescope-run-here') === undefined) { class RunHere extends HTMLElement { constructor() { super() } connectedCallback() { const run = child => { const fn = new Function(child.textContent); child.textContent = \"\"; fn.call(this); this.remove(); }; const child = this.querySelector(\"script\"); if (child) { run(child); } else { new MutationObserver(()=>{ run(this.querySelector(\"script\")); }).observe(this, {childList: true}); } } } customElements.define(\"treescope-run-here\", RunHere); } })(); </script> <treescope-container class=\"treescope_out_bd219e4e14e14d99998d03b2d380114d\" style=\"display:block\"></treescope-container> <treescope-run-here><script type=\"application/octet-stream\"> const root = ( Array.from(document.getElementsByClassName( \"treescope_out_bd219e4e14e14d99998d03b2d380114d\")) .filter((elt) => !elt.dataset.setup) )[0]; root.dataset.setup = 1; const msg = document.createElement(\"span\"); msg.style = \"color: #cccccc; font-family: monospace;\"; msg.textContent = \"(Loading...)\"; root.state.loadingMsg = msg; root.shadowRoot.appendChild(msg); root.state.chain = new Promise((resolve, reject) => { const observer = new IntersectionObserver((entries) => { for (const entry of entries) { if (entry.isIntersecting) { resolve(); observer.disconnect(); return; } } }, {rootMargin: \"1000px\"}); window.setTimeout(() => { observer.observe(root); }, 0); }); root.state.deferring = false; const _insertNode = (node) => { for (let oldScript of node.querySelectorAll(\"script\")) { let newScript = document.createElement(\"script\"); newScript.type = oldScript.type; newScript.textContent = oldScript.textContent; oldScript.parentNode.replaceChild(newScript, oldScript); } if (root.state.loadingMsg) { root.state.loadingMsg.remove(); root.state.loadingMsg = null; } root.shadowRoot.appendChild(node); }; root.defns.insertContent = ((contentNode, compressed) => { if (compressed) { root.state.deferring = true; } if (root.state.deferring) { root.state.chain = (async () => { await root.state.chain; if (compressed) { const encoded = contentNode.textContent; const blob = new Blob([ Uint8Array.from(atob(encoded), (m) => m.codePointAt(0)) ]); const reader = blob.stream().pipeThrough( new DecompressionStream(\"deflate\") ).pipeThrough( new TextDecoderStream(\"utf-8\") ).getReader(); const parts = []; while (true) { const step = await reader.read(); if (step.done) { break; } parts.push(step.value); } const tpl = document.createElement('template'); tpl.innerHTML = parts.join(\"\"); _insertNode(tpl.content); } else { _insertNode(contentNode.content); } })(); } else { _insertNode(contentNode.content); } }); </script></treescope-run-here><div style=\"display:none\"> <script type=\"application/octet-stream\" >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</script> <treescope-run-here><script type=\"application/octet-stream\"> const root = ( Array.from(document.getElementsByClassName( \"treescope_out_bd219e4e14e14d99998d03b2d380114d\")) .filter((elt) => !elt.dataset['step0']) )[0]; root.dataset['step0'] = 1; root.defns.insertContent( this.parentNode.querySelector('script[type=\"application/octet-stream\"]'), true ); this.parentNode.remove(); </script></treescope-run-here> </div>"
      ],
      "text/plain": [
       "<IPython.core.display.HTML object>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "text/html": [
       "<div style=\"display:none\"> <script type=\"application/octet-stream\" >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</script> <treescope-run-here><script type=\"application/octet-stream\"> const root = ( Array.from(document.getElementsByClassName( \"treescope_out_bd219e4e14e14d99998d03b2d380114d\")) .filter((elt) => !elt.dataset['step1']) )[0]; root.dataset['step1'] = 1; root.defns.insertContent( this.parentNode.querySelector('script[type=\"application/octet-stream\"]'), true ); this.parentNode.remove(); </script></treescope-run-here> </div>"
      ],
      "text/plain": [
       "<IPython.core.display.HTML object>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "class LoraParam(nnx.Param): pass\n",
    "\n",
    "class LoraLinear(nnx.Module):\n",
    "  def __init__(self, linear: Linear, rank: int, rngs: nnx.Rngs):\n",
    "    self.linear = linear\n",
    "    self.A = LoraParam(rngs.normal((linear.din, rank)))\n",
    "    self.B = LoraParam(rngs.normal((rank, linear.dout)))\n",
    "\n",
    "  def __call__(self, x: jax.Array):\n",
    "    return self.linear(x) + x @ self.A @ self.B\n",
    "\n",
    "rngs = nnx.Rngs(0)\n",
    "model = MLP(2, 32, 5, rngs=rngs)\n",
    "\n",
    "# Model surgery.\n",
    "model.linear1 = LoraLinear(model.linear1, 4, rngs=rngs)\n",
    "model.linear2 = LoraLinear(model.linear2, 4, rngs=rngs)\n",
    "\n",
    "y = model(x=jnp.ones((3, 2)), rngs=rngs)\n",
    "\n",
    "nnx.display(model)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Flax transformations\n",
    "\n",
    "[Flax NNX transformations (transforms)](https://flax.readthedocs.io/en/latest/guides/jax_and_nnx_transforms.html) extend [JAX transforms](https://jax.readthedocs.io/en/latest/key-concepts.html#transformations) to support `Module`s and other objects. They serve as supersets of their equivalent JAX counterparts with the addition of being aware of the object's state and providing additional APIs to transform it.\n",
    "\n",
    "One of the main features of Flax Transforms is the preservation of reference semantics, meaning that any mutation of the object graph that occurs inside the transform is propagated outside as long as it is legal within the transform rules. In practice this means that Flax programs can be expressed using imperative code, highly simplifying the user experience.\n",
    "\n",
    "In the following example, you define a `train_step` function that takes a `MLP` model, an `Optimizer`, and a batch of data, and returns the loss for that step. The loss and the gradients are computed using the `nnx.value_and_grad` transform over the `loss_fn`. The gradients are passed to the optimizer's `update` method to update the model's parameters."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "loss = Array(1.0000616, dtype=float32)\n",
      "optimizer.step.value = Array(1, dtype=uint32)\n"
     ]
    }
   ],
   "source": [
    "import optax\n",
    "\n",
    "# An MLP containing 2 custom `Linear` layers, 1 `nnx.Dropout` layer, 1 `nnx.BatchNorm` layer.\n",
    "model = MLP(2, 16, 10, rngs=nnx.Rngs(0))\n",
    "optimizer = nnx.Optimizer(model, optax.adam(1e-3), wrt=nnx.Param)\n",
    "\n",
    "@nnx.jit  # Automatic state management\n",
    "def train_step(model, optimizer, x, y, rngs):\n",
    "  def loss_fn(model: MLP, rngs: nnx.Rngs):\n",
    "    y_pred = model(x, rngs)\n",
    "    return jnp.mean((y_pred - y) ** 2)\n",
    "\n",
    "  loss, grads = nnx.value_and_grad(loss_fn)(model, rngs)\n",
    "  optimizer.update(model, grads)  # In place updates.\n",
    "\n",
    "  return loss\n",
    "\n",
    "x, y = jnp.ones((5, 2)), jnp.ones((5, 10))\n",
    "loss = train_step(model, optimizer, x, y, rngs)\n",
    "\n",
    "print(f'{loss = }')\n",
    "print(f'{optimizer.step.value = }')"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "There are two things happening in this example that are worth mentioning:\n",
    "\n",
    "1. The updates to each of the `BatchNorm` and `Dropout` layer's state is automatically propagated from within `loss_fn` to `train_step` all the way to the `model` reference outside.\n",
    "2. The `optimizer` holds a mutable reference to the model - this relationship is preserved inside the train_step function making it possible to update the model's parameters using the optimizer alone.\n",
    "\n",
    "> **Note**<br> `nnx.jit` has performance overhead for small models, check the [Performance Considerations](https://flax.readthedocs.io/en/latest/guides/performance.html) guide for more information.\n",
    "\n",
    "### Scan over layers\n",
    "\n",
    "The next example uses Flax `nnx.vmap` to create a stack of multiple MLP layers and `nnx.scan` to iteratively apply each layer of the stack to the input.\n",
    "\n",
    "In the code below notice the following:\n",
    "\n",
    "1. The custom `create_model` function takes in a key and returns an `MLP` object, since you create five keys and use `nnx.vmap` over `create_model` a stack of 5 `MLP` objects is created.\n",
    "2. The `nnx.scan` is used to iteratively apply each `MLP` in the stack to the input `x`.\n",
    "3. The nnx.scan (consciously) deviates from `jax.lax.scan` and instead mimics nnx.vmap, which is more expressive. nnx.scan allows specifying multiple inputs, the scan axes of each input/output, and the position of the carry.\n",
    "4. `State` updates for `BatchNorm` layers are automatically propagated by nnx.scan.\n",
    "5. The `rngs` object is split into separate streams for each layer using the `fork` method."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "metadata": {},
   "outputs": [],
   "source": [
    "@nnx.vmap(in_axes=0, out_axes=0)\n",
    "def create_model(rngs):\n",
    "  return MLP(10, 32, 10, rngs=rngs)\n",
    "\n",
    "@nnx.scan(in_axes=(0, 0, nnx.Carry), out_axes=nnx.Carry)\n",
    "def forward(model: MLP, rngs: nnx.Rngs, x):\n",
    "  x = model(x, rngs)\n",
    "  return x\n",
    "    \n",
    "param_rngs = nnx.Rngs(0).fork(split=5)\n",
    "model = create_model(param_rngs)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 10,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "y.shape = (3, 10)\n"
     ]
    },
    {
     "data": {
      "text/html": [
       "<script> (()=>{ if (customElements.get('treescope-container') === undefined) { class TreescopeContainer extends HTMLElement { constructor() { super(); this.attachShadow({mode: \"open\"}); this.defns = {}; this.state = {}; } } customElements.define(\"treescope-container\", TreescopeContainer); } if (customElements.get('treescope-run-here') === undefined) { class RunHere extends HTMLElement { constructor() { super() } connectedCallback() { const run = child => { const fn = new Function(child.textContent); child.textContent = \"\"; fn.call(this); this.remove(); }; const child = this.querySelector(\"script\"); if (child) { run(child); } else { new MutationObserver(()=>{ run(this.querySelector(\"script\")); }).observe(this, {childList: true}); } } } customElements.define(\"treescope-run-here\", RunHere); } })(); </script> <treescope-container class=\"treescope_out_21eca24c3bc14e6c8b5b9ad2200499bd\" style=\"display:block\"></treescope-container> <treescope-run-here><script type=\"application/octet-stream\"> const root = ( Array.from(document.getElementsByClassName( \"treescope_out_21eca24c3bc14e6c8b5b9ad2200499bd\")) .filter((elt) => !elt.dataset.setup) )[0]; root.dataset.setup = 1; const msg = document.createElement(\"span\"); msg.style = \"color: #cccccc; font-family: monospace;\"; msg.textContent = \"(Loading...)\"; root.state.loadingMsg = msg; root.shadowRoot.appendChild(msg); root.state.chain = new Promise((resolve, reject) => { const observer = new IntersectionObserver((entries) => { for (const entry of entries) { if (entry.isIntersecting) { resolve(); observer.disconnect(); return; } } }, {rootMargin: \"1000px\"}); window.setTimeout(() => { observer.observe(root); }, 0); }); root.state.deferring = false; const _insertNode = (node) => { for (let oldScript of node.querySelectorAll(\"script\")) { let newScript = document.createElement(\"script\"); newScript.type = oldScript.type; newScript.textContent = oldScript.textContent; oldScript.parentNode.replaceChild(newScript, oldScript); } if (root.state.loadingMsg) { root.state.loadingMsg.remove(); root.state.loadingMsg = null; } root.shadowRoot.appendChild(node); }; root.defns.insertContent = ((contentNode, compressed) => { if (compressed) { root.state.deferring = true; } if (root.state.deferring) { root.state.chain = (async () => { await root.state.chain; if (compressed) { const encoded = contentNode.textContent; const blob = new Blob([ Uint8Array.from(atob(encoded), (m) => m.codePointAt(0)) ]); const reader = blob.stream().pipeThrough( new DecompressionStream(\"deflate\") ).pipeThrough( new TextDecoderStream(\"utf-8\") ).getReader(); const parts = []; while (true) { const step = await reader.read(); if (step.done) { break; } parts.push(step.value); } const tpl = document.createElement('template'); tpl.innerHTML = parts.join(\"\"); _insertNode(tpl.content); } else { _insertNode(contentNode.content); } })(); } else { _insertNode(contentNode.content); } }); </script></treescope-run-here><div style=\"display:none\"> <script type=\"application/octet-stream\" >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</script> <treescope-run-here><script type=\"application/octet-stream\"> const root = ( Array.from(document.getElementsByClassName( \"treescope_out_21eca24c3bc14e6c8b5b9ad2200499bd\")) .filter((elt) => !elt.dataset['step0']) )[0]; root.dataset['step0'] = 1; root.defns.insertContent( this.parentNode.querySelector('script[type=\"application/octet-stream\"]'), true ); this.parentNode.remove(); </script></treescope-run-here> </div>"
      ],
      "text/plain": [
       "<IPython.core.display.HTML object>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "text/html": [
       "<div style=\"display:none\"> <script type=\"application/octet-stream\" >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</script> <treescope-run-here><script type=\"application/octet-stream\"> const root = ( Array.from(document.getElementsByClassName( \"treescope_out_21eca24c3bc14e6c8b5b9ad2200499bd\")) .filter((elt) => !elt.dataset['step1']) )[0]; root.dataset['step1'] = 1; root.defns.insertContent( this.parentNode.querySelector('script[type=\"application/octet-stream\"]'), true ); this.parentNode.remove(); </script></treescope-run-here> </div>"
      ],
      "text/plain": [
       "<IPython.core.display.HTML object>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "x = jnp.ones((3, 10))\n",
    "dropout_rngs = nnx.Rngs(1).fork(split=5)\n",
    "y = forward(model, dropout_rngs, x)\n",
    "\n",
    "print(f'{y.shape = }')\n",
    "nnx.display(model)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "How do Flax NNX transforms achieve this? To understand how Flax NNX objects interact with JAX transforms, the next section explains the Flax NNX Functional API."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## The Flax Functional API\n",
    "\n",
    "The Flax NNX Functional API establishes a clear boundary between reference/object semantics and value/pytree semantics. It also allows the same amount of fine-grained control over the state that Flax Linen and Haiku users are used to. The Flax NNX Functional API consists of three basic methods:  `nnx.split`, `nnx.merge`, and `nnx.update`.\n",
    "\n",
    "Below is an example of of `StatefulLinear` `Module` that uses the Functional API. It contains:\n",
    "\n",
    "- Some `Param` Variables; and\n",
    "- A custom `Count` Variable type, which is used to track the integer scalar state that increases on every forward pass."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 10,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<script> (()=>{ if (customElements.get('treescope-container') === undefined) { class TreescopeContainer extends HTMLElement { constructor() { super(); this.attachShadow({mode: \"open\"}); this.defns = {}; this.state = {}; } } customElements.define(\"treescope-container\", TreescopeContainer); } if (customElements.get('treescope-run-here') === undefined) { class RunHere extends HTMLElement { constructor() { super() } connectedCallback() { const run = child => { const fn = new Function(child.textContent); child.textContent = \"\"; fn.call(this); this.remove(); }; const child = this.querySelector(\"script\"); if (child) { run(child); } else { new MutationObserver(()=>{ run(this.querySelector(\"script\")); }).observe(this, {childList: true}); } } } customElements.define(\"treescope-run-here\", RunHere); } })(); </script> <treescope-container class=\"treescope_out_28c54a9a4cf8476087ce1c9723f4630a\" style=\"display:block\"></treescope-container> <treescope-run-here><script type=\"application/octet-stream\"> const root = ( Array.from(document.getElementsByClassName( \"treescope_out_28c54a9a4cf8476087ce1c9723f4630a\")) .filter((elt) => !elt.dataset.setup) )[0]; root.dataset.setup = 1; const msg = document.createElement(\"span\"); msg.style = \"color: #cccccc; font-family: monospace;\"; msg.textContent = \"(Loading...)\"; root.state.loadingMsg = msg; root.shadowRoot.appendChild(msg); root.state.chain = new Promise((resolve, reject) => { const observer = new IntersectionObserver((entries) => { for (const entry of entries) { if (entry.isIntersecting) { resolve(); observer.disconnect(); return; } } }, {rootMargin: \"1000px\"}); window.setTimeout(() => { observer.observe(root); }, 0); }); root.state.deferring = false; const _insertNode = (node) => { for (let oldScript of node.querySelectorAll(\"script\")) { let newScript = document.createElement(\"script\"); newScript.type = oldScript.type; newScript.textContent = oldScript.textContent; oldScript.parentNode.replaceChild(newScript, oldScript); } if (root.state.loadingMsg) { root.state.loadingMsg.remove(); root.state.loadingMsg = null; } root.shadowRoot.appendChild(node); }; root.defns.insertContent = ((contentNode, compressed) => { if (compressed) { root.state.deferring = true; } if (root.state.deferring) { root.state.chain = (async () => { await root.state.chain; if (compressed) { const encoded = contentNode.textContent; const blob = new Blob([ Uint8Array.from(atob(encoded), (m) => m.codePointAt(0)) ]); const reader = blob.stream().pipeThrough( new DecompressionStream(\"deflate\") ).pipeThrough( new TextDecoderStream(\"utf-8\") ).getReader(); const parts = []; while (true) { const step = await reader.read(); if (step.done) { break; } parts.push(step.value); } const tpl = document.createElement('template'); tpl.innerHTML = parts.join(\"\"); _insertNode(tpl.content); } else { _insertNode(contentNode.content); } })(); } else { _insertNode(contentNode.content); } }); </script></treescope-run-here><div style=\"display:none\"> <script type=\"application/octet-stream\" >eNrtW4tX2zrS/1d0c8+3OAsxzvtB4axD82oLLYSWtrt7srIt22oc29hKQtjD//6NZOfhxAmwF9rt3YYekkijmdG89BuZvgrZzCEnMgsICXXPJ4PA8xj6N/K9kDLquQ0UEAczOiFHyPRcljPxiDqzBhp5rhf6WIfxqU0ZyYkvDeQHMOLQkOUE6xyb+TDqei4Ma1gfWoE3do2c7jle0IiWHqH4m+YAAfCjBrMbyKQMyFxGXHaERtTNxeN5Rfk/4OXd5kJ6R10L1nmBQYIcDB0hHxsGDOYcYrIGKug218YlOZtQy4aRvFzm8lyGKWxuwT/+kJvQkGrUoQy2iMfMW9DmqMsC6oZU52JJNBvv6/7VYWTHVws75oKxCzIDGAv1gPoMcUMc72Hfd6iOuWkPPZ0RbqaA4NHeiSRlj0/A8iAvZMggphuiY8RsGsoWYZfglnPPIFJWtr2QyWIetkYYGvjE5VtWdc6VL/r7P9Nmutg1HALT7thxjiIJMqjZ9zwXRqWpFwyzaFUH7xqG+FRimFGdD/okML1ghF2dyK43lbIiEECAtDGDctGiV6hYyAIfaiJpTWvZIa7FbHR8jBROslP1gLBx4ILdEXFCslTMHrtcs3XWoU1NxvUTBPzDPfxskSBB+LmGN5UDcjMmIVNdOhLuagd4RKTIJlnO42hDkD8O7ciMRyl7nIs4jraxY5eP14FrETmSeZblROk7ECkG0epzXnyEOOwAkQkEeOxJrp34Lg/JjBs9E2S4QjGxrDs4DN9BFsd8pcyC52AEYZiZC7/Pgj0h/EWMn7w6TEsAg06QYHicSdaZDGJYg52S2+OMkoHUDdgmieeCimAMF6Z2JUO6BSS+Zr73DCRjVO80jzFvxAtDw/WYJJueY2ANVrvAtmHjUDpxsEack+TMIJIh1jR0m+hDYmSz6K/cdPPCwzy/gRQ5XyajzdLDx+5yYsvw/Si1zN7LohwOsKYFZCKiW1TH3yu1AlaUJYHujUawrRUKLF7cNWskOFLZ9iYkyKbQx+RgaQhfY4WjAi/TXFAQY8C3tCSIS/ZmZZ/gQMrlNMfTh9FQ9mhep4WF8v4tCj2HGrsoIzc9RHzPA4AEXDkf1CE2uIwEq2ap8p/4ABMR0ECUYSjEfHHCw1uOPjBoWiAAtUFDEDqbH3HrhOgEiUBqNDQCRXHFcr/r4pUeA9Hplcvz4ys+9sDxC1nUFYElzLBDpnD3pmQDB8OQYAsSzd1c/UwJsdCBL01fNKdPaCiO4Qba+0ehrOl7P1K95KKtSla+g5Lcj1zwOAi5A30PwAgJUuTS8PnEilQQgnKifIbbYvx5pC63x8gt25Qi03Bg0iBkA8+NitBmau1KJblQ5tmU6ir0h9WPPL6uIt/VCAcWwMdIDZHQ939QGpRif6aNoTS6qQVoOZ0WtBmUWaMCQwJ4Tyf+B8mXjMwa9t87wxAVFDuoPxtpnhOi92PG92ug02glvPszSIzclGhDwPFR5R3B0WwLxI5dBsspDomxQP+/E4X/HG2GebRaoG5FrvMzNLnLKD9SdpFe7pYr5SkOBzqcA2DYxXpsssTpMa/Tu2SurUmKXDV9fIAZmOEcdsGxAtdlV4e5EA5WA+zOo1mwRfkQEbAYwIecN2ZP28pCA3AMJcZvSU2ESPQbHflewLC7wVsLvCFxB3xkWYwetu7KshV7zt18L9u6PRBt44BnxwqGipJFkaOMXaELOJJaIQwiZLWg5MgKtmoMdGhFjIC48eaTzR5omSR8NhC4SMb4aE4kv44dXYKOFNohADQCQcshw3z9Qt8X0yRGVJEmBuAqCBMOq1bccTPGjgsNxgB6eJPeApNE4tVE4kE3hTnSmuLABQ8M5kfF3LumifV8MYXQh3Zkw3GiHsZGiodysTOXkLIhYDQOclaADQpuk1C+WDaIdYA8SBKLIAXUq+j2QZQ00EfwEiSGUGzmDV02avXzHARoo+TnFsG57uttsblOt4DekQ8hu5Mk3z16Fbmk29nH6Pp9wjlqDYRWqQ1CojUT+wCfODZ4S8rDdlaXxHxDoCJZ3mLHNlguzT1+7VzuvI0RKxcs56O5ePg7WnPZiAkL5nhejcN4g3kygt1t31gKhnoygnkoxP+d6BUj//Jq9YhecTfxvQwcX6TvXzr5j7T+UxsOTN75pyE7DrTBeKk0UUu4QgW6bmMUcQCTONgHBPZwF/t0B2+XsFQ0IiK3AFWMrTTPoUeaiIQplhdmaaZI3kjJyZswtIPD+lbdxN1cOuFjhG3l84zX0fyGEP2mBgGeyWbgjSTD08f8LknmoCCUJ9gZEwi0rBx6IyIJqMDvFvm7HDUK/F7xka1CZg8OzuziJje0CWH8updM0Wm/3+e76fMxfnkrJuWAiLue/szVpX/9LW5PdDIHLU9vVVYvh1x+fe3EY9M4h0v87i0M9AYaB47EcXODzx9OPdMsHGmAzCulA0Opd84stamKV+9CVT3xqXk5hd/dtqq21F2v5khVraH31ui1mqfTL6p69eX0jXrWa56qbeu2131ns7B5RolVbL/+XHjXq3yZ9P0x/XBWvsq/+dy7/HQ2uT67Yx9m7fbp/rU1vKLN14pNX1+M37SMzjelqx2ak57h37yt2DfXlF6Mz9yO3TU/MvVjpXkelNR2zx22KvrH8djdvyzf6OFwOjHbzuHNrdXyapb2Ztqp5bvqoatelt8FwZv85b51p1waivrGzFvn1dNp51vBUrzZ+LJaHbXylWn3c/29ZfnkajgrkZ52V9a14H2HYdW66J1PX+NwFl6Me73P1632VP1w4fe+GB8PD/et6lX1c5Ep5tsPN+qkDDzfqedV9Wyqjqy7y/7++GuftD7fFsyKfndeuuzOyuOm+vau+c1v+0XavThtKV/HH0r9qms237W67bORSvdrk1bBdvN2dV/7NP38bdoNJq87H0/db2arZbH99/pXx6mW66dvps2aXS+dnXX6xc5X1Rr1yt+aF3V21SHdeqvZ7HWKr63S5eEXfaapHfDpp7eH6kUHq+Ts1FG7d6331ldmVZofrPfve6+bQ3pRJu3m59NmW6eKbwee70Js+F9br/N3+WHfPDWZPXvrdg3cDrumcj7qtM4rTUO9+fTJxyzsfx0ZBqb1gnlXL32k324q/iiovPe+nPZp0BlN3nSK/et+sd0q6M0L82q/63h+p9QOp2Vs3VRq9Cvpnzv+tdvs9ohxFpDx9U3ndJS/bgfDfv+2XKhcX4dTFTTKIvHohkl7Iqz3+JH5L/i1yH5seD70DsuUFA+cZFneQXEQ5ew/gdfuK3xbPAERDWPUywJvCA9XR1LUUiafT0EKXnk8fYEsbjn5WAjlgbPgPTRvPPEUU4ZcPKEWZl4gA2df83BgyNOAMnJFbpm05MURRcRr+RAEjngps9Jg88cfIOWKjgh04tL8+djGuoCMoFveWHp/gAqKoggkBcUXUKskrorS5a500ZmlcvySbF7B+BOjDPodtTF1oLAxD3Hi30RlA7TpQl8H1ZiCzQg2+CXA/qrt4kc5DzzE4RcKSJTH40wCVDWQN3R0GyB1tVbm6EcpomKxLtdqJaVYLCjFfKGMDgEBwX7TACW/2c7E/OOnRMnb7PVGDYgjBPCKuv44Psky4szXvNtMKpMYHsBkBA1gk2JxUm7iEUeME1HykmJN0+TZnzn5i8O4IYFiN11icq3vhtmYQ/TWZ3CEmWPnnWiCpcVkbIQNMXO0k0nZ3PyBUOYEwuUDDjAA1oKCpJqCmtkDCJgxvyXKI6kkvl95DDtAAQM1PpJUbJX93hxu7iWH+dDAmTjJ4cxGK5zE/5kd1Buk0+PtwfNHYiU9Rl7G46aDb2XXvQVYBWAFNHGoJietLbwlpbl9b3nltoc895QXmuO9J1Za8aA0u4cW94HHGXmaWWb8YhwwlTzlV7vrl5gwIeoJnFc2fI63fLI9Zp4YrvkykirKc0bhxm1hZtd85kRg3uNHuJkax5nFM8lKAWuKQWp6Ta+XMNbrRrFSrdQ1M1/K13BZWROa9iwzDrP0nX6D0BE4HaVZZNEsCsI5iel4mBULUvEAlbN/sZYh/ICzEp1H6m5LxXqpaurVilbNlxS9rJVreqlarSgVpVCvlWu7Sv3zZGtaYfxvMmr0drBp3EW7DOH+1HTZVW5erj5EXeDWKhFNP0+tWK8HUBA+0RDqKL0THJFNDchWQDlo2Rrznvk/Cumf3HAPJvN6ZQOMZVMI5eMUm8d/FJI5aWMnJI8IzIMnBu8Lmnm+r+2WnlM8s7G3H1ErtWNXgG/DFat/G5Q5gb7rEcmyWYuyuzHNBv3zVqufCrBsT6LdsFT7BUtfyMvaNi9rPwKWAiot/ISoVCuYZrmGC1qhXi7lCwouG3W9YBSIrutaXjd+JCotHzwvJq2UyoVitUiUYqFSyufzWl2p1iumrsM/DET/A5h0p0n/PIhU2w2stF+I9AcZ7hcijc38ECLVfiHSPxMifQms8p8iUp3f7v4JUGnSAOLO+vsCUGHIbY4Vkz/kfjS6tf+vwKEJ+FWsKQXFKNfrpFIpFfVivUKUgp6vYL1ULBFi/gioOaYuh0XZn7awiDDbfWivkLxEsfnfOLEjIz50aiepfp3cu07un8ftL1Tif0Ynb39OvvyvlGjt7/QzTw+Nx5+Fc0qDTk7+H2PbAQY=</script> <treescope-run-here><script type=\"application/octet-stream\"> const root = ( Array.from(document.getElementsByClassName( \"treescope_out_28c54a9a4cf8476087ce1c9723f4630a\")) .filter((elt) => !elt.dataset['step0']) )[0]; root.dataset['step0'] = 1; root.defns.insertContent( this.parentNode.querySelector('script[type=\"application/octet-stream\"]'), true ); this.parentNode.remove(); </script></treescope-run-here> </div>"
      ],
      "text/plain": [
       "<IPython.core.display.HTML object>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "text/html": [
       "<div style=\"display:none\"> <script type=\"application/octet-stream\" >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</script> <treescope-run-here><script type=\"application/octet-stream\"> const root = ( Array.from(document.getElementsByClassName( \"treescope_out_28c54a9a4cf8476087ce1c9723f4630a\")) .filter((elt) => !elt.dataset['step1']) )[0]; root.dataset['step1'] = 1; root.defns.insertContent( this.parentNode.querySelector('script[type=\"application/octet-stream\"]'), true ); this.parentNode.remove(); </script></treescope-run-here> </div>"
      ],
      "text/plain": [
       "<IPython.core.display.HTML object>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "class Count(nnx.Variable): pass\n",
    "\n",
    "class StatefulLinear(nnx.Module):\n",
    "  def __init__(self, din: int, dout: int, *, rngs: nnx.Rngs):\n",
    "    self.w = nnx.Param(rngs.uniform((din, dout)))\n",
    "    self.b = nnx.Param(jnp.zeros((dout,)))\n",
    "    self.count = Count(jnp.array(0, dtype=jnp.uint32))\n",
    "\n",
    "  def __call__(self, x: jax.Array):\n",
    "    self.count.value += 1\n",
    "    return x @ self.w + self.b\n",
    "\n",
    "model = StatefulLinear(din=3, dout=5, rngs=nnx.Rngs(0))\n",
    "y = model(jnp.ones((1, 3)))\n",
    "\n",
    "nnx.display(model)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### State and GraphDef\n",
    "\n",
    "A Flax `Module` can be decomposed into `State` and `GraphDef` using the `nnx.split` function:\n",
    "\n",
    "- `State` is a `Mapping` from strings to `Variable`s or nested  `State`s.\n",
    "- `GraphDef` contains all the static information needed to reconstruct a `Module` graph, it is analogous to [JAX's `PyTreeDef`](https://jax.readthedocs.io/en/latest/pytrees.html#internal-pytree-handling)."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 12,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<script> (()=>{ if (customElements.get('treescope-container') === undefined) { class TreescopeContainer extends HTMLElement { constructor() { super(); this.attachShadow({mode: \"open\"}); this.defns = {}; this.state = {}; } } customElements.define(\"treescope-container\", TreescopeContainer); } if (customElements.get('treescope-run-here') === undefined) { class RunHere extends HTMLElement { constructor() { super() } connectedCallback() { const run = child => { const fn = new Function(child.textContent); child.textContent = \"\"; fn.call(this); this.remove(); }; const child = this.querySelector(\"script\"); if (child) { run(child); } else { new MutationObserver(()=>{ run(this.querySelector(\"script\")); }).observe(this, {childList: true}); } } } customElements.define(\"treescope-run-here\", RunHere); } })(); </script> <treescope-container class=\"treescope_out_32bf0ff96e2e4ea099a433e87574fd1e\" style=\"display:block\"></treescope-container> <treescope-run-here><script type=\"application/octet-stream\"> const root = ( Array.from(document.getElementsByClassName( \"treescope_out_32bf0ff96e2e4ea099a433e87574fd1e\")) .filter((elt) => !elt.dataset.setup) )[0]; root.dataset.setup = 1; const msg = document.createElement(\"span\"); msg.style = \"color: #cccccc; font-family: monospace;\"; msg.textContent = \"(Loading...)\"; root.state.loadingMsg = msg; root.shadowRoot.appendChild(msg); root.state.chain = new Promise((resolve, reject) => { const observer = new IntersectionObserver((entries) => { for (const entry of entries) { if (entry.isIntersecting) { resolve(); observer.disconnect(); return; } } }, {rootMargin: \"1000px\"}); window.setTimeout(() => { observer.observe(root); }, 0); }); root.state.deferring = false; const _insertNode = (node) => { for (let oldScript of node.querySelectorAll(\"script\")) { let newScript = document.createElement(\"script\"); newScript.type = oldScript.type; newScript.textContent = oldScript.textContent; oldScript.parentNode.replaceChild(newScript, oldScript); } if (root.state.loadingMsg) { root.state.loadingMsg.remove(); root.state.loadingMsg = null; } root.shadowRoot.appendChild(node); }; root.defns.insertContent = ((contentNode, compressed) => { if (compressed) { root.state.deferring = true; } if (root.state.deferring) { root.state.chain = (async () => { await root.state.chain; if (compressed) { const encoded = contentNode.textContent; const blob = new Blob([ Uint8Array.from(atob(encoded), (m) => m.codePointAt(0)) ]); const reader = blob.stream().pipeThrough( new DecompressionStream(\"deflate\") ).pipeThrough( new TextDecoderStream(\"utf-8\") ).getReader(); const parts = []; while (true) { const step = await reader.read(); if (step.done) { break; } parts.push(step.value); } const tpl = document.createElement('template'); tpl.innerHTML = parts.join(\"\"); _insertNode(tpl.content); } else { _insertNode(contentNode.content); } })(); } else { _insertNode(contentNode.content); } }); </script></treescope-run-here><div style=\"display:none\"> <script type=\"application/octet-stream\" >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</script> <treescope-run-here><script type=\"application/octet-stream\"> const root = ( Array.from(document.getElementsByClassName( \"treescope_out_32bf0ff96e2e4ea099a433e87574fd1e\")) .filter((elt) => !elt.dataset['step0']) )[0]; root.dataset['step0'] = 1; root.defns.insertContent( this.parentNode.querySelector('script[type=\"application/octet-stream\"]'), true ); this.parentNode.remove(); </script></treescope-run-here> </div>"
      ],
      "text/plain": [
       "<IPython.core.display.HTML object>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "text/html": [
       "<script> (()=>{ if (customElements.get('treescope-container') === undefined) { class TreescopeContainer extends HTMLElement { constructor() { super(); this.attachShadow({mode: \"open\"}); this.defns = {}; this.state = {}; } } customElements.define(\"treescope-container\", TreescopeContainer); } if (customElements.get('treescope-run-here') === undefined) { class RunHere extends HTMLElement { constructor() { super() } connectedCallback() { const run = child => { const fn = new Function(child.textContent); child.textContent = \"\"; fn.call(this); this.remove(); }; const child = this.querySelector(\"script\"); if (child) { run(child); } else { new MutationObserver(()=>{ run(this.querySelector(\"script\")); }).observe(this, {childList: true}); } } } customElements.define(\"treescope-run-here\", RunHere); } })(); </script> <treescope-container class=\"treescope_out_6f65c96f779b472d80b1a08ca4e9bf96\" style=\"display:block\"></treescope-container> <treescope-run-here><script type=\"application/octet-stream\"> const root = ( Array.from(document.getElementsByClassName( \"treescope_out_6f65c96f779b472d80b1a08ca4e9bf96\")) .filter((elt) => !elt.dataset.setup) )[0]; root.dataset.setup = 1; const msg = document.createElement(\"span\"); msg.style = \"color: #cccccc; font-family: monospace;\"; msg.textContent = \"(Loading...)\"; root.state.loadingMsg = msg; root.shadowRoot.appendChild(msg); root.state.chain = new Promise((resolve, reject) => { const observer = new IntersectionObserver((entries) => { for (const entry of entries) { if (entry.isIntersecting) { resolve(); observer.disconnect(); return; } } }, {rootMargin: \"1000px\"}); window.setTimeout(() => { observer.observe(root); }, 0); }); root.state.deferring = false; const _insertNode = (node) => { for (let oldScript of node.querySelectorAll(\"script\")) { let newScript = document.createElement(\"script\"); newScript.type = oldScript.type; newScript.textContent = oldScript.textContent; oldScript.parentNode.replaceChild(newScript, oldScript); } if (root.state.loadingMsg) { root.state.loadingMsg.remove(); root.state.loadingMsg = null; } root.shadowRoot.appendChild(node); }; root.defns.insertContent = ((contentNode, compressed) => { if (compressed) { root.state.deferring = true; } if (root.state.deferring) { root.state.chain = (async () => { await root.state.chain; if (compressed) { const encoded = contentNode.textContent; const blob = new Blob([ Uint8Array.from(atob(encoded), (m) => m.codePointAt(0)) ]); const reader = blob.stream().pipeThrough( new DecompressionStream(\"deflate\") ).pipeThrough( new TextDecoderStream(\"utf-8\") ).getReader(); const parts = []; while (true) { const step = await reader.read(); if (step.done) { break; } parts.push(step.value); } const tpl = document.createElement('template'); tpl.innerHTML = parts.join(\"\"); _insertNode(tpl.content); } else { _insertNode(contentNode.content); } })(); } else { _insertNode(contentNode.content); } }); </script></treescope-run-here><div style=\"display:none\"> <script type=\"application/octet-stream\" >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</script> <treescope-run-here><script type=\"application/octet-stream\"> const root = ( Array.from(document.getElementsByClassName( \"treescope_out_6f65c96f779b472d80b1a08ca4e9bf96\")) .filter((elt) => !elt.dataset['step0']) )[0]; root.dataset['step0'] = 1; root.defns.insertContent( this.parentNode.querySelector('script[type=\"application/octet-stream\"]'), true ); this.parentNode.remove(); </script></treescope-run-here> </div>"
      ],
      "text/plain": [
       "<IPython.core.display.HTML object>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "text/html": [
       "<div style=\"display:none\"> <script type=\"application/octet-stream\" >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</script> <treescope-run-here><script type=\"application/octet-stream\"> const root = ( Array.from(document.getElementsByClassName( \"treescope_out_6f65c96f779b472d80b1a08ca4e9bf96\")) .filter((elt) => !elt.dataset['step1']) )[0]; root.dataset['step1'] = 1; root.defns.insertContent( this.parentNode.querySelector('script[type=\"application/octet-stream\"]'), true ); this.parentNode.remove(); </script></treescope-run-here> </div>"
      ],
      "text/plain": [
       "<IPython.core.display.HTML object>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "graphdef, state = nnx.split(model)\n",
    "\n",
    "nnx.display(graphdef, state)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Split, merge, and update\n",
    "\n",
    "Flax's `nnx.merge` is the reverse of `nnx.split`. It takes the `GraphDef` + `State` and reconstructs the `Module`. The example below demonstrates this as follows:\n",
    "\n",
    "- By using `nnx.split` and `nnx.merge` in sequence any `Module` can be lifted to be used in any JAX transform.\n",
    "- `nnx.update` can update an object in place with the content of a given `State`.\n",
    "- This pattern is used to propagate the state from a transform back to the source object outside."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 13,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "model.count.value = Array(1, dtype=uint32)\n",
      "model.count.value = Array(2, dtype=uint32)\n"
     ]
    }
   ],
   "source": [
    "print(f'{model.count.value = }')\n",
    "\n",
    "# 1. Use `nnx.split` to create a pytree representation of the `nnx.Module`.\n",
    "graphdef, state = nnx.split(model)\n",
    "\n",
    "@jax.jit\n",
    "def forward(graphdef: nnx.GraphDef, state: nnx.State, x: jax.Array) -> tuple[jax.Array, nnx.State]:\n",
    "  # 2. Use `nnx.merge` to create a new model inside the JAX transformation.\n",
    "  model = nnx.merge(graphdef, state)\n",
    "  # 3. Call the `nnx.Module`\n",
    "  y = model(x)\n",
    "  # 4. Use `nnx.split` to propagate `nnx.State` updates.\n",
    "  _, state = nnx.split(model)\n",
    "  return y, state\n",
    "\n",
    "y, state = forward(graphdef, state, x=jnp.ones((1, 3)))\n",
    "# 5. Update the state of the original `nnx.Module`.\n",
    "nnx.update(model, state)\n",
    "\n",
    "print(f'{model.count.value = }')"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "The key insight of this pattern is that using mutable references is fine within a transform context (including the base eager interpreter) but it is necessary to use the Functional API when crossing boundaries.\n",
    "\n",
    "**Why aren't Modules just pytrees?** The main reason is that it is very easy to lose track of shared references by accident this way, for example if you pass two `Module`s that have a shared Module through a JAX boundary, you will silently lose that sharing. Flax's Functional API makes this behavior explicit, and thus it is much easier to reason about."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Fine-grained State control\n",
    "\n",
    "Experienced [Flax Linen](https://flax-linen.readthedocs.io/) or [Haiku](https://dm-haiku.readthedocs.io/) API users may recognize that having all the states in a single structure is not always the best choice as there are cases in which you may want to handle different subsets of the state differently. This is a common occurrence when interacting with [JAX transforms](https://jax.readthedocs.io/en/latest/key-concepts.html#transformations).\n",
    "\n",
    "For example:\n",
    "\n",
    "- Not every model state can or should be differentiated when interacting with `jax.grad`.\n",
    "- Or, sometimes, there is a need to specify what part of the model's state is a carry and what part is not when using `jax.lax.scan`.\n",
    "\n",
    "To address this, the Flax NNX API has `nnx.split`, which allows you to pass one or more `Filter`s to partition the `Variable`s into mutually exclusive `State`s. Flax NNx uses `Filter` create `State` groups in APIs (such as `nnx.split`, `nnx.state`, and many of NNX transforms).\n",
    "\n",
    "The example below shows the most common `Filter`s:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 14,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<script> (()=>{ if (customElements.get('treescope-container') === undefined) { class TreescopeContainer extends HTMLElement { constructor() { super(); this.attachShadow({mode: \"open\"}); this.defns = {}; this.state = {}; } } customElements.define(\"treescope-container\", TreescopeContainer); } if (customElements.get('treescope-run-here') === undefined) { class RunHere extends HTMLElement { constructor() { super() } connectedCallback() { const run = child => { const fn = new Function(child.textContent); child.textContent = \"\"; fn.call(this); this.remove(); }; const child = this.querySelector(\"script\"); if (child) { run(child); } else { new MutationObserver(()=>{ run(this.querySelector(\"script\")); }).observe(this, {childList: true}); } } } customElements.define(\"treescope-run-here\", RunHere); } })(); </script> <treescope-container class=\"treescope_out_736a46b5462b429b9b1259685d90555c\" style=\"display:block\"></treescope-container> <treescope-run-here><script type=\"application/octet-stream\"> const root = ( Array.from(document.getElementsByClassName( \"treescope_out_736a46b5462b429b9b1259685d90555c\")) .filter((elt) => !elt.dataset.setup) )[0]; root.dataset.setup = 1; const msg = document.createElement(\"span\"); msg.style = \"color: #cccccc; font-family: monospace;\"; msg.textContent = \"(Loading...)\"; root.state.loadingMsg = msg; root.shadowRoot.appendChild(msg); root.state.chain = new Promise((resolve, reject) => { const observer = new IntersectionObserver((entries) => { for (const entry of entries) { if (entry.isIntersecting) { resolve(); observer.disconnect(); return; } } }, {rootMargin: \"1000px\"}); window.setTimeout(() => { observer.observe(root); }, 0); }); root.state.deferring = false; const _insertNode = (node) => { for (let oldScript of node.querySelectorAll(\"script\")) { let newScript = document.createElement(\"script\"); newScript.type = oldScript.type; newScript.textContent = oldScript.textContent; oldScript.parentNode.replaceChild(newScript, oldScript); } if (root.state.loadingMsg) { root.state.loadingMsg.remove(); root.state.loadingMsg = null; } root.shadowRoot.appendChild(node); }; root.defns.insertContent = ((contentNode, compressed) => { if (compressed) { root.state.deferring = true; } if (root.state.deferring) { root.state.chain = (async () => { await root.state.chain; if (compressed) { const encoded = contentNode.textContent; const blob = new Blob([ Uint8Array.from(atob(encoded), (m) => m.codePointAt(0)) ]); const reader = blob.stream().pipeThrough( new DecompressionStream(\"deflate\") ).pipeThrough( new TextDecoderStream(\"utf-8\") ).getReader(); const parts = []; while (true) { const step = await reader.read(); if (step.done) { break; } parts.push(step.value); } const tpl = document.createElement('template'); tpl.innerHTML = parts.join(\"\"); _insertNode(tpl.content); } else { _insertNode(contentNode.content); } })(); } else { _insertNode(contentNode.content); } }); </script></treescope-run-here><div style=\"display:none\"> <script type=\"application/octet-stream\" >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</script> <treescope-run-here><script type=\"application/octet-stream\"> const root = ( Array.from(document.getElementsByClassName( \"treescope_out_736a46b5462b429b9b1259685d90555c\")) .filter((elt) => !elt.dataset['step0']) )[0]; root.dataset['step0'] = 1; root.defns.insertContent( this.parentNode.querySelector('script[type=\"application/octet-stream\"]'), true ); this.parentNode.remove(); </script></treescope-run-here> </div>"
      ],
      "text/plain": [
       "<IPython.core.display.HTML object>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "text/html": [
       "<div style=\"display:none\"> <script type=\"application/octet-stream\" >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</script> <treescope-run-here><script type=\"application/octet-stream\"> const root = ( Array.from(document.getElementsByClassName( \"treescope_out_736a46b5462b429b9b1259685d90555c\")) .filter((elt) => !elt.dataset['step1']) )[0]; root.dataset['step1'] = 1; root.defns.insertContent( this.parentNode.querySelector('script[type=\"application/octet-stream\"]'), true ); this.parentNode.remove(); </script></treescope-run-here> </div>"
      ],
      "text/plain": [
       "<IPython.core.display.HTML object>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "text/html": [
       "<script> (()=>{ if (customElements.get('treescope-container') === undefined) { class TreescopeContainer extends HTMLElement { constructor() { super(); this.attachShadow({mode: \"open\"}); this.defns = {}; this.state = {}; } } customElements.define(\"treescope-container\", TreescopeContainer); } if (customElements.get('treescope-run-here') === undefined) { class RunHere extends HTMLElement { constructor() { super() } connectedCallback() { const run = child => { const fn = new Function(child.textContent); child.textContent = \"\"; fn.call(this); this.remove(); }; const child = this.querySelector(\"script\"); if (child) { run(child); } else { new MutationObserver(()=>{ run(this.querySelector(\"script\")); }).observe(this, {childList: true}); } } } customElements.define(\"treescope-run-here\", RunHere); } })(); </script> <treescope-container class=\"treescope_out_d9ecfb6392a34945a6aadf520b5db673\" style=\"display:block\"></treescope-container> <treescope-run-here><script type=\"application/octet-stream\"> const root = ( Array.from(document.getElementsByClassName( \"treescope_out_d9ecfb6392a34945a6aadf520b5db673\")) .filter((elt) => !elt.dataset.setup) )[0]; root.dataset.setup = 1; const msg = document.createElement(\"span\"); msg.style = \"color: #cccccc; font-family: monospace;\"; msg.textContent = \"(Loading...)\"; root.state.loadingMsg = msg; root.shadowRoot.appendChild(msg); root.state.chain = new Promise((resolve, reject) => { const observer = new IntersectionObserver((entries) => { for (const entry of entries) { if (entry.isIntersecting) { resolve(); observer.disconnect(); return; } } }, {rootMargin: \"1000px\"}); window.setTimeout(() => { observer.observe(root); }, 0); }); root.state.deferring = false; const _insertNode = (node) => { for (let oldScript of node.querySelectorAll(\"script\")) { let newScript = document.createElement(\"script\"); newScript.type = oldScript.type; newScript.textContent = oldScript.textContent; oldScript.parentNode.replaceChild(newScript, oldScript); } if (root.state.loadingMsg) { root.state.loadingMsg.remove(); root.state.loadingMsg = null; } root.shadowRoot.appendChild(node); }; root.defns.insertContent = ((contentNode, compressed) => { if (compressed) { root.state.deferring = true; } if (root.state.deferring) { root.state.chain = (async () => { await root.state.chain; if (compressed) { const encoded = contentNode.textContent; const blob = new Blob([ Uint8Array.from(atob(encoded), (m) => m.codePointAt(0)) ]); const reader = blob.stream().pipeThrough( new DecompressionStream(\"deflate\") ).pipeThrough( new TextDecoderStream(\"utf-8\") ).getReader(); const parts = []; while (true) { const step = await reader.read(); if (step.done) { break; } parts.push(step.value); } const tpl = document.createElement('template'); tpl.innerHTML = parts.join(\"\"); _insertNode(tpl.content); } else { _insertNode(contentNode.content); } })(); } else { _insertNode(contentNode.content); } }); </script></treescope-run-here><div style=\"display:none\"> <script type=\"application/octet-stream\" >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</script> <treescope-run-here><script type=\"application/octet-stream\"> const root = ( Array.from(document.getElementsByClassName( \"treescope_out_d9ecfb6392a34945a6aadf520b5db673\")) .filter((elt) => !elt.dataset['step0']) )[0]; root.dataset['step0'] = 1; root.defns.insertContent( this.parentNode.querySelector('script[type=\"application/octet-stream\"]'), true ); this.parentNode.remove(); </script></treescope-run-here> </div>"
      ],
      "text/plain": [
       "<IPython.core.display.HTML object>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "text/html": [
       "<div style=\"display:none\"> <script type=\"application/octet-stream\" >eNqNUk1v2zAM/SuCBhQOsrhuEuRjtgNs7Qb0ssN22KEoAlWiYw2K5VFyMGPofx9lOy6ydcAukii+9yg+MVP6xJxvDeRcaVcb0b5jla2AM61yXljcKygAEdQ+uVktN+vNdr5MYLmAZLteL25Wm3lSwGqptiu+y1wtqn5l0gjnci6tIQ3x9IRw4rsr49Pv4mf8HlG00fwtU76tIW905RfzydXBp9l1r3He6H27zCOAk7aGGTbVrAQEKiJR1551fC7q2mgpvLbVtZUe/MwRRxz5TtrKEUrgAfy9cixnD/z/O3pMe76yEq31xPaldjFpfaHws1UQTVI21KBHDqABHv9oANuvYEB6ixGPxz72Ic3/ot4acj4UGeJYhouujMcGCD9mEOivJHzTvowu6KNogeJwhGp4TxOOsSRTPNwN4acBEXo4o2OyEip1W2qjRuGQt8giA55p0ktS2rIXV2MD1cGXdDudTtgvFnB9ksCjMoUfDYTjh/aexM/sB/1IBQLH2QYl3NFI/tPDN2EkOZuyP+h9eGHLqBYXGt25dtcZEV6yCEd76j7y+fInXjV5Eka0mz2azlcG8zfsOCrd</script> <treescope-run-here><script type=\"application/octet-stream\"> const root = ( Array.from(document.getElementsByClassName( \"treescope_out_d9ecfb6392a34945a6aadf520b5db673\")) .filter((elt) => !elt.dataset['step1']) )[0]; root.dataset['step1'] = 1; root.defns.insertContent( this.parentNode.querySelector('script[type=\"application/octet-stream\"]'), true ); this.parentNode.remove(); </script></treescope-run-here> </div>"
      ],
      "text/plain": [
       "<IPython.core.display.HTML object>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "# Use `nnx.Variable` type `Filter`s to split into multiple `nnx.State`s.\n",
    "graphdef, params, counts = nnx.split(model, nnx.Param, Count)\n",
    "\n",
    "nnx.display(params, counts)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "**Note:** `Filter`s must be exhaustive, if a value is not matched an error will be raised.\n",
    "\n",
    "As expected, the `nnx.merge` and `nnx.update` methods naturally consume multiple `State`s:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 15,
   "metadata": {},
   "outputs": [],
   "source": [
    "# Merge multiple `State`s\n",
    "model = nnx.merge(graphdef, params, counts)\n",
    "# Update with multiple `State`s\n",
    "nnx.update(model, params, counts)"
   ]
  }
 ],
 "metadata": {
  "jupytext": {
   "formats": "ipynb,md:myst"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.11.6"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 4
}
